import path from 'node:path'
import { SYMBOLS } from '../../src/types/interfaces'
import { Logger } from './logger'

/**
 * 模块副作用处理器 - 处理 treeshake 模块副作用配置
 */
export class ModuleSideEffectsProcessor {
  private readonly name: string = 'ModuleSideEffectsProcessor'
  private readonly sideEffectsModules: Set<string>
  private readonly processedCache: Map<string, boolean> = new Map() // 缓存已处理的模块
  private processedCount: number = 0
  private preservedCount: number = 0
  private loggedModules: Set<string> = new Set() // 记录已打印日志的模块

  constructor(modules: string[]) {
    this.sideEffectsModules = new Set(modules)
    Logger.info(`检测到 ${modules.length} 个需要保留副作用的模块`, this.name)
  }

  /**
   * 判断模块是否需要保留副作用
   * @param moduleId - 模块 ID（完整路径）
   * @returns 是否需要保留副作用
   */
  shouldPreserveSideEffects(moduleId: string): boolean {
    const moduleKey = this.getModuleKey(moduleId)

    // 检查缓存
    if (this.processedCache.has(moduleKey)) {
      return this.processedCache.get(moduleKey)!
    }

    this.processedCount++

    const filename = this.extractFilename(moduleId)
    const shouldPreserve = this.sideEffectsModules.has(filename)

    // 缓存结果
    this.processedCache.set(moduleKey, shouldPreserve)

    if (shouldPreserve) {
      this.preservedCount++

      // 只在第一次处理时打印日志
      if (!this.loggedModules.has(moduleKey)) {
        this.loggedModules.add(moduleKey)

        Logger.info(
          `${SYMBOLS.NETWORK.LOCK} 保留模块副作用: ${filename}`,
          'TreeShake',
        )
      }
    }
    // else {
    //   Logger.info(`${SYMBOLS.UI.CYCLONE} 正常摇树处理: ${filename}`, 'TreeShake')
    // }

    // if (this.processedCount === this.sideEffectsModules.size)
    //   this.printSummary()

    return shouldPreserve
  }

  /**
   * 获取处理统计信息
   */
  getStats(): { processed: number, preserved: number, cached: number, uniqueModules: number } {
    return {
      processed: this.processedCount,
      preserved: this.preservedCount,
      cached: this.processedCache.size,
      uniqueModules: this.loggedModules.size,
    }
  }

  /**
   * 打印详细处理摘要
   */
  printDetailedSummary(): void {
    const stats = this.getStats()
    const uniquePreserved = this.loggedModules.size

    Logger.success(
      `模块处理统计:
      📊 总处理次数: ${stats.processed}
      🔍 唯一模块数: ${stats.uniqueModules}
      🔒 保留副作用: ${stats.preserved} 次 (${uniquePreserved} 个唯一模块)
      💾 缓存命中: ${stats.cached} 次`,
      'TREESHAKE_SUMMARY',
    )

    // 打印保留的模块列表
    if (uniquePreserved > 0) {
      const moduleList = Array.from(this.loggedModules).join(', ')
      Logger.info(`保留的模块: ${moduleList}`, 'TREESHAKE_DETAILS')
    }
  }

  /**
   * 打印简洁处理摘要
   */
  printSummary(): void {
    const stats = this.getStats()
    Logger.success(
      `模块处理完成: 处理 ${stats.processed} 次，保留 ${stats.preserved} 次副作用 (${this.loggedModules.size} 个唯一模块)`,
      'TREESHAKE_SUMMARY',
    )
  }

  /**
   * 提取文件名（不含扩展名）
   * @param filePath - 文件路径
   * @returns 纯文件名（不含路径和扩展名）
   */
  private extractFilename(filePath: string): string {
    try {
      const basename = path.basename(filePath)
      // 移除文件扩展名
      return basename.replace(/\.[^/.]+$/, '')
    }
    // eslint-disable-next-line unused-imports/no-unused-vars
    catch (error) {
      Logger.warn(`提取文件名失败: ${filePath}`, 'FILENAME_EXTRACT')
      return filePath
    }
  }

  /**
   * 获取模块的唯一标识（基于文件名和部分路径）
   * @param moduleId - 模块 ID
   * @returns 模块唯一标识
   */
  private getModuleKey(moduleId: string): string {
    // 使用文件名作为基础，避免路径差异导致的重复
    return this.extractFilename(moduleId)
  }

  /**
   * 清空缓存（用于开发环境热重载）
   */
  clearCache(): void {
    this.processedCache.clear()
    this.loggedModules.clear()
    Logger.info('模块处理器缓存已清空', this.name)
  }
}
